package billingServer;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import server.data.Bid;

/**
 *
 * @author Group 95
 */
public class BillingServerSecure extends UnicastRemoteObject implements IBillingServerSecure 
{
    private static final Logger logger = Logger.getLogger("BillingServerSecure");
    
    private PriceSteps priceSteps;
    private HashMap<String, UserAuctions> bills;
    
    
    public BillingServerSecure() throws RemoteException
    {
        super();
        logger.setLevel(Level.OFF);
        priceSteps=new PriceSteps();
        bills = new HashMap<String, UserAuctions>();
    }

    @Override
    public synchronized PriceSteps getPriceSteps() throws RemoteException
    {
        logger.info("BillingServerSecure getPriceSteps()");
        if(priceSteps==null)
        {
            throw new RemoteException("Error: priceSteps null.");
        }
        return priceSteps;
    }

    /**
     * Creates new PriceStep
     * Throw Remote Exception if parameters for new step are invalid (negative)
     * or step collides with existing PriceStep.
     * @param startPrice
     * @param endPrice
     * @param fixedPrice
     * @param variablePricePercent
     * @throws RemoteException 
     */
    @Override
    public synchronized void createPriceStep(double startPrice, double endPrice, double fixedPrice, double variablePricePercent) throws RemoteException {
        if(! priceSteps.addStep(startPrice, endPrice, fixedPrice, variablePricePercent))
        {
            throw new RemoteException("Error while creating new price step!");
        }
    }

    @Override
    public synchronized void deletePriceStep(double startPrice, double endPrice) throws RemoteException {
        if(! priceSteps.removeStep(startPrice, endPrice))
        {
            throw new RemoteException("Error: Price step ["+startPrice+" "+endPrice+"] does not exist!");
        }
    }

    @Override
    public synchronized void billAuction(Bid bid) {
        logger.log(Level.INFO, "New auctionBill: Bid {0}", new Object[]{bid});
        UserAuctions auctions;
        if ((auctions= bills.get(bid.getBidder().getStrName()))==null) {
            logger.info("User has no auctionBills yet, add new");
            auctions=new UserAuctions();
            bills.put(bid.getBidder().getStrName(),auctions);
        }else {
            logger.info("User already has bill");
        }
        logger.log(Level.INFO, "Add auction to auctionBills: Bid {1}", new Object[]{bid});
        auctions.addAuction(bid.getAuctionId(), bid.getdPrice());
    }

    @Override
    public synchronized Bill getBill(String user) {
        if (bills.containsKey(user)) {
            UserAuctions tempUserAuctions = bills.get(user);
            HashMap<Long, Double> tempUserAuctionsValues = tempUserAuctions.getAuctions();
            ArrayList<AuctionBill> userAuctionBills = new ArrayList<AuctionBill>();
            
            for(Map.Entry<Long, Double> e : tempUserAuctionsValues.entrySet()) {
                userAuctionBills.add(new AuctionBill(e.getKey(), e.getValue(), priceSteps));
            }
            return new Bill(user, userAuctionBills);
        }
        logger.info("No bills for user available.");
        return null;
        
    }

}
